﻿using SupportLayer.Enums;
using SupportLayer.Objetos.Elementos;
using SupportLayer.Objetos.Placa;
using System;
using System.Linq;
using System.Web.UI.WebControls;

namespace SupportLayer.Util.ExtensionMethods
{
	public static class Methods
	{
		#region PlacaClass
		public static void CalculatePlaca(this PlacaClass Placa)
		{
			// esse for faz o cálculo de height, width, razao e gap de cada linha
			for (int iLinha = 0; iLinha < Placa.Linhas.Count; iLinha++)
			{
				LinhaClass linha = Placa.Linhas[iLinha];

				// adiciona a largura de todos os elementos na largura da linha
				foreach (ElementoClass elemento in linha.Elements)
					linha.Width += elemento.Width;

				if (linha.hasPictograma() < 0)
					if (iLinha > 0 && Placa.Linhas[iLinha - 1].hasPictograma() >= 0)
						Placa.Linhas[iLinha - 1].Elements.ForEach(a =>
							linha.Width += a.Element is PictogramaClass ? a.Element.GetWidth() : 0);

				// baseia-se na altura da letra de 100mm.
				linha.Razao = (double)linha.AlturaLetra / 100;
				linha.Gap = Util.Espacamento.Round((int)Enums.EspacamentoLetra100.EntreElementos, linha.Razao);
				linha.Width += (linha.Gap * (linha.Elements.Count + 1));
				linha.GapRound = Util.Espacamento.RoundGap(linha.Width, (int)Placa.ArredondamentoHorizontal);

				if ((iLinha > 0) && (Placa.Linhas[iLinha - 1].AgruparSeta))
					linha.Height = (int)linha.AlturaLetra + linha.Gap;
				else
					linha.Height = (int)linha.AlturaLetra + linha.Gap * 2;
			}

			var largest = Placa.Linhas.OrderByDescending(a => a.Width).First();
			Placa.Gap = largest.Gap;
			Placa.AlturaLetra = largest.AlturaLetra;
			Placa.Width = largest.Width;

			Placa.Border = ((int)Placa.AlturaLetra < 225) ? 20 : 50;
			Placa.Margin = ((int)Placa.AlturaLetra < 225) ? 10 : 25;
			Placa.Radius = ((int)Placa.AlturaLetra < 225) ? 30 : 70;

			Placa.Width += (Placa.Border * 2) + (Placa.Margin * 2);
			Placa.GapWidthRound = Util.Espacamento.RoundGap(Placa.Width, (int)Placa.ArredondamentoHorizontal);
			Placa.RoundedWidth = Placa.Width + Placa.GapWidthRound;

			int height = Placa.Border * 2 + Placa.Margin * 2;

			for (int iLinha = 0; iLinha < Placa.Linhas.Count; iLinha++)
			{
				LinhaClass linha = Placa.Linhas[iLinha];
				if (iLinha > 0)
					if (linha.CorTexto != Placa.Linhas[iLinha - 1].CorTexto)
						height += Placa.Border * 2 + Placa.Margin * 2;
			}

			if (Placa.Linhas.Count == 1)
				Placa.Height = largest.Height + height;
			else
			{
				Placa.Height = 0;
				for (int iLinha = 0; iLinha < Placa.Linhas.Count; iLinha++)
				{
					LinhaClass linha = Placa.Linhas[iLinha];

					if (iLinha > 0)
						if (Placa.Linhas[iLinha - 1].AgruparSeta)
							if (linha.AgruparSeta)
								height += linha.Height;
							else
								if (iLinha != Placa.Linhas.Count - 1)
									height += Placa.Border + linha.Height;
								else
									height += linha.Height;
						else
							if (linha.AgruparSeta)
								height += linha.Height;
							else
								if (iLinha < Placa.Linhas.Count - 1)
									height += Placa.Border + linha.Height;
								else
									height += linha.Height;
					else
						if (linha.AgruparSeta)
							height += linha.Height;
						else
							if (iLinha < Placa.Linhas.Count - 1)
								height += Placa.Border + linha.Height;
							else
								height += linha.Height;
				}

				Placa.Height += height;
				//Placa.Height = ((Placa.Border * 2) + (Placa.Margin * 2) + largest.Height) * Placa.Linhas.Count();
			}

			Placa.GapHeightRound = Util.Espacamento.RoundGap(Placa.Height, (int)Placa.ArredondamentoVertical);
			Placa.RoundedHeight += Placa.Height + Placa.GapHeightRound;
		}
		#endregion PlacaClass

		#region LinhaClass

		/// <summary>
		/// Verifica se há seta ou pictograma na placa, ou se é apenas texto.
		/// Se houver apenas texto, a diferença do arredondamento deve ser dividido por 2 e
		/// adicionado dos dois lados do texto. Senão a diferença deve ser colocada na
		/// extremidade mais distante da seta.
		/// </summary>
		/// <param name="linha"></param>
		/// <returns></returns>
		public static bool isOnlyText(this LinhaClass linha)
		{
			if ((linha.Elements.Count == 1) && (linha.Elements[0].Element is MensagemClass))
				return true;
			return false;
		}

		/// <summary>
		/// Confere se há seta na linha para fazer o alinhamento. Se não houver, inicia a
		/// seta como S1O, para alinhar o texto a esquerda da placa.
		/// </summary>
		/// <param name="linha"></param>
		/// <returns></returns>
		public static TipoSeta hasSeta(this LinhaClass linha)
		{
			for (int y = 0; y < linha.Elements.Count; y++)
				if (linha.Elements[y].Element is SetaClass)
					return ((SetaClass)linha.Elements[y].Element).GetTipoSeta();

			return TipoSeta.S1O;
		}

		public static int hasPictograma(this LinhaClass linha)
		{
			for (int x = 0; x < linha.Elements.Count; x++)
				if (linha.Elements[x].Element is PictogramaClass)
					return x;
			return -1;
		}

		#endregion LinhaClass

		#region Controls

		public static void AddCssClass(this WebControl Control, string _cssClass)
		{
			if (string.IsNullOrEmpty(Control.CssClass))
				Control.CssClass = _cssClass;
			else
			{
				string[] cssClasses = Control.CssClass.Split(' ');
				bool classExists = cssClasses.Any(@class => @class == _cssClass);

				if (!classExists)
				{
					Control.CssClass += " " + _cssClass;
				}
			}
		}

		public static void RemoveCssClass(this WebControl Control, string _cssClass)
		{
			if (!string.IsNullOrEmpty(Control.CssClass))
			{
				string[] cssClasses = Control.CssClass.Split(' ');
				Control.CssClass = string.Join(" ", cssClasses.Where(@class => @class != _cssClass).ToArray());
			}
		}

		#endregion Controls

		#region Objects

		public static bool isNull(this object obj)
		{
			return obj == null;
		}

		#endregion Objects

		#region Date
		public static string toQueryDate(this DateTime _date)
		{
			try
			{
				string year, month, day;
				year = _date.Year.ToString();
				month = _date.Month.ToString();
				day = _date.Day.ToString();

				return "'" + year + "-" + month + "-" + day + "'";
			}
			catch (Exception)
			{

				throw;
			}
		}
		#endregion
	}
}